Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AnimatedTexture: Fix crash when loaded from a thread #93340

Merged
merged 1 commit into from
Jun 19, 2024

Conversation

RandomShaper
Copy link
Member

Signals (like most, or all?, of the Object API) is not thread-safe. AnimatedTexture tries to connect to RenderingServer's singal frame_pre_draw in the constructor. The issue is that such constructor may be running on any thread.

An alternative solution would be to make all the signal API in Object virtual so that RenderingServer can wrap all the functions with the server_wrap_mt_common.h utilities. However, that would harm performance in every other case.

In conclusion, it's OK to consider the specification for writing resource classes to include it should only deal with thread-safe APIs.

AnimatedTexture::AnimatedTexture() {
//proxy = RS::get_singleton()->texture_create();
proxy_ph = RS::get_singleton()->texture_2d_placeholder_create();
proxy = RS::get_singleton()->texture_proxy_create(proxy_ph);

RenderingServer::get_singleton()->texture_set_force_redraw_if_visible(proxy, true);
RenderingServer::get_singleton()->connect("frame_pre_draw", callable_mp(this, &AnimatedTexture::_update_proxy));

MessageQueue::get_main_singleton()->push_callable(callable_mp(this, &AnimatedTexture::_finish_non_thread_safe_setup));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't using the CONNECT_DEFERRED flag achieve something similar without having to introduce a new method?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, but this is another case of the difference between the main call queue and the thread override call queue is relevant. CONNECT_DEFERRED would use MessageQueue::get_singleton(), which during threaded loading wouldn't be the good old default MessageQueue, but the override the ResourceLoader has set for the loading thread. We need to bypass it.

Maybe we could consider making that a bit more transparent. However, as I see things, we are in a de facto stage of colllection of information about the needs of resources dealing with a multi-threaded world and we're not ready yet to come up with solid API designs that are better than the manual approaches.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, thanks for the details!

@akien-mga akien-mga merged commit 9a4942f into godotengine:master Jun 19, 2024
16 checks passed
@akien-mga
Copy link
Member

Thanks!

@RandomShaper RandomShaper deleted the fix_anim_text_thread branch June 19, 2024 09:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants